#include "PARStemCell.h"
#include "main.h"
#include "cmath"
#include <string>

double PARStemCell::calcDistance(class PARStemCell & sys_par )
{
    if( !IsMutated ){
        return 0;
    }
    else {
    double s = 0;
    for(int i =0;i <NUMMUTPAR;i ++){
    s += pow((sys_par.getPar(i) - this->getPar(i))/sys_par.getPar(i),2);
    }
    s = sqrt(s*1.0/(NUMMUTPAR));
    return(s);
    }
}

double& PARStemCell::getPar(int index)
{
    if(index >= NUMMUTPAR || index < 0)
    {
        printf("Wrong index in getPar!\n");
        printf("%d\n",index);
        exit(0);
    }
    switch (index)
    {
    case 0:
    return(this->a1);
    case 1:
    return(this->a2);
    case 2:
    return(this->a3);
    case 3:
    return(this->a4);
    case 4:
    return(this->alpha1);
    case 5:
    return(this->alpha2);
    case 6:
    return(this->beta0);
    case 7:
    return(this->b1);
    case 8:
    return(this->eta);
    case 9:
    return(this->kappa0);
    case 10:
    return(this->mu0);
    case 11:
    return(this->tau);
    case 12:
    return(this->theta0);
    case 13:
    return(this->d1);
    case 14:
    return(this->d2);
    case 15:
    return(this->c1);
    case 16:
    return(this->lambda);
    case 17:
    return(this->phi0);
    case 18:
    return(this->z0);
    }
    return (this->a1);
}

// 拷贝构造函数
PARStemCell::PARStemCell(const PARStemCell& other)
{
        beta0 = other.beta0;
        kappa0 = other.kappa0;
        a1 = other.a1;
        a2 = other.a2;
        a3 = other.a3;
        a4 = other.a4;
        b1 = other.b1;
        eta = other.eta;
        d1 = other.d1;
        d2 = other.d2;
        mu0 = other.mu0;
        tau = other.tau;
        c1 = other.c1;
        theta0 = other.theta0;
        alpha1 = other.alpha1;
        alpha2 = other.alpha2;
        lambda = other.lambda;
        phi0 = other.phi0;
        z0 = other.z0;
        IsMutated = other.IsMutated;
}

void PARStemCell::readPar(std::string filename)
{
    std::ifstream file(filename);
    std::string line;

    // 读取文件的每一行
    while (std::getline(file, line)) {
        // 使用stringstream来分割行
        std::istringstream iss(line);
        std::string key, value;
        if (std::getline(iss, key, '=')) {
            iss >> value;

            // 根据键填充结构体
            if (key == "beta0") {
                this->beta0 = std::stod(value);
            } else if (key == "kappa0") {
                this->kappa0 = std::stod(value);
            } else if (key == "theta0") {
                this->theta0 = std::stod(value);
            } else if (key == "eta") {
                this->eta = std::stod(value);
            } else if (key == "p_a1") {
                this->a1 = std::stod(value);
            } else if (key == "p_a2") {
                this->a2 = std::stod(value);
            } else if (key == "p_a3") {
                this->a3 = std::stod(value);
            } else if (key == "p_a4") {
                this->a4 = std::stod(value);
            } else if (key == "p_b1") {
                this->b1 = std::stod(value);
            } else if (key == "p_d1") {
                this->d1 = std::stod(value);
            } else if (key == "p_d2") {
                this->d2 = std::stod(value);
            } else if (key == "p_c1") {
                this->c1 = std::stod(value);
            } else if (key == "mu") {
                this->mu0 = std::stod(value);
            } else if (key == "tau") {
                this->tau = std::stod(value);
            } else if (key == "z0") {
                this->z0 = std::stod(value);
            } else if (key == "phi0") {
                this->phi0 = std::stod(value);
            } else if (key == "alpha1") {
                this->alpha1 = std::stod(value);
            } else if (key == "alpha2") {
                this->alpha2 = std::stod(value);
            } else if (key == "lambda") {
                this->lambda = std::stod(value);
            }
            // 跳过 varsigma 和 mutationrate
        }
    }
}

PARStemCell& PARStemCell::operator=(const PARStemCell& other) 
{
        if (this != &other) { // 检查自赋值
            beta0 = other.beta0;
            kappa0 = other.kappa0;
            a1 = other.a1;
            a2 = other.a2;
            a3 = other.a3;
            a4 = other.a4;
            b1 = other.b1;
            eta = other.eta;
            d1 = other.d1;
            d2 = other.d2;
            mu0 = other.mu0;
            tau = other.tau;
            c1 = other.c1;
            theta0 = other.theta0;
            alpha1 = other.alpha1;
            alpha2 = other.alpha2;
            lambda = other.lambda;
            phi0 = other.phi0;
            z0 = other.z0;
            IsMutated = other.IsMutated;
        }
        return *this; // 返回引用，以便链式赋值
    }

void PARStemCell::printAllElements(std::string msg) const
{
    std::cout << msg << "\n";
    std::cout << "beta0: " << beta0 << "  ";
    std::cout << "kappa0: " << kappa0 <<"  ";
    std::cout << "a1: " << a1 <<"   ";
    std::cout << "a2: " << a2 << std::endl;
    std::cout << "a3: " << a3 << "  ";
    std::cout << "a4: " << a4 << "  ";
    std::cout << "b1: " << b1 << "  ";
    std::cout << "eta: " << eta << std::endl;
    std::cout << "d1: " << d1 <<"  ";
    std::cout << "d2: " << d2 <<"  ";
    std::cout << "mu0: " << mu0 <<"  ";
    std::cout << "tau: " << tau << std::endl;
    std::cout << "c1: " << c1 <<"  ";
    std::cout << "theta0: " << theta0<< "  " ;
    std::cout << "alpha1: " << alpha1 <<"  ";
    std::cout << "alpha2: " << alpha2 << std::endl;
    std::cout << "lambda: " << lambda <<"  ";
    std::cout << "phi0: " << phi0 <<"  ";
    std::cout << "z0: " << z0 <<"  \n";
}